#include<bits/stdc++.h>
using namespace std;
struct node{
    int pos;
    int st_v;
    int ad_v;
}car[100005];
int chk[100005],cnt=0;
bool link[3005][3005];
int n,m,len,vt;
int Search(int val){
    int tag=1;
    while(chk[tag]<val)tag++;
    return tag;
}
int Search2(int val){
    int tag=m;
    while(chk[tag]>val)tag--;
    return tag;
}
int main(){
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    cin>>t;
    while(t--){
        cin>>n>>m>>len>>vt;
        for(int i=1;i<=n;i++)cin>>car[i].pos>>car[i].st_v>>car[i].ad_v;
        for(int i=1;i<=m;i++)cin>>chk[i];
        memset(link,false,sizeof(link));
        for(int i=1;i<=n;i++){
            int Min_pos;
            if(car[i].ad_v>0){
                Min_pos=(vt*vt-car[i].st_v*car[i].st_v)/(2*car[i].ad_v)+car[i].pos;
                if(Min_pos<=chk[m])cnt++;
                else continue;
                int temp=Search(Min_pos);
                for(int j=temp;j<=m;j++)link[temp][i]=link[i][temp]=true;
            }
            else if(car[i].ad_v==0){
                if(car[i].st_v>=vt){
                    cnt++;
                    int temp=Search(Min_pos);
                    for(int j=temp;j<=m;j++)link[j][i]=link[i][j]=true;
                }
            }
            if(car[i].ad_v<0){
                Min_pos=(car[i].st_v*car[i].st_v-vt*vt)/(2*car[i].ad_v)+car[i].pos;
                if(Min_pos>=chk[1])cnt++;
                else continue;
                int temp=Search2(Min_pos),temp1=Search(car[i].pos);
                for(int j=temp1;j<=temp;j++)link[j][i]=link[i][j]=true;
            }
        }
        cout<<cnt<<endl;

    }
    return 0;
}
